import cgi
import datetime
import logging
import os

from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import images
from google.appengine.ext.webapp import template

from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter

from model import BlogEntry
from model import CommentEntry

import BlogRender

class MainPage(webapp.RequestHandler):
  def get(self):
      template_values = {
          'Table': 'Entry'
      }
      self.generate('base.html', template_values)
      
  def generate(self, template_name, template_values={}):
      user = users.get_current_user()
      #if not user:
      #    return self.redirect(users.create_login_url(self.request.uri))
      recentBlogs = BlogEntry.gql("ORDER BY create_date DESC LIMIT 6")
      if not recentBlogs:
          recentBlogs = []
      
      values = {
          'request': self.request,
          'user': users.get_current_user(),
          'recentBlogs': recentBlogs,
          'login_url': users.create_login_url(self.request.uri),
          'logout_url': users.create_logout_url('http://%s/' % (
              self.request.host,)),
          'debug': self.request.get('deb'),
          'isAdmin': users.is_current_user_admin(),
          'application_name': 'Code Blogger',}
      values.update(template_values)
      directory = os.path.dirname(__file__)
      path = os.path.join(directory, os.path.join('templates', template_name))
      self.response.out.write(template.render(path, values, debug=True))


class CreateEditBlog(MainPage):
    def get(self):
        if not users.is_current_user_admin():
            return self.redirect(users.create_login_url(self.request.uri))
        template_values = {}
        blogEntryKey = self.request.get("blog_id")
        if blogEntryKey:
            editBlog = BlogEntry.get(blogEntryKey)
            template_values['editBlog'] = editBlog            
        
        self.generate('CreateEditBlog.html', template_values)

class CreateEditBlogDo(MainPage):
    def post(self):
        #TODO this should create a new entry based upon the textarea
        user = users.get_current_user()
        if not users.is_current_user_admin():
            return self.redirect(users.create_login_url(self.request.uri))
        
        newBlogTitle = self.request.get('titleInput')
        newBlogMarkdown = self.request.get('textarea')
        editBlogKey = self.request.get('EditBlogKey')
        logging.log(logging.INFO, "User: " + user.email() + " posted create.do with Title: " +
                    newBlogTitle + "\nText ***\n" + newBlogMarkdown + "\n***")
        blogEntry = BlogEntry()
        if editBlogKey:
            blogEntry = BlogEntry.get(editBlogKey)
        blogEntry.author = user
        blogEntry.title = newBlogTitle
        blogEntry.markdown = newBlogMarkdown
        blogEntry.html = BlogRender.render(newBlogMarkdown)
        
        blogEntry.put()

        self.redirect('/ViewBlogEntry?blog_id=%s' % blogEntry.key()) #TODO redirect to the newly created blog post

class AddCommentToBlogDo(MainPage):
    def post(self):
        #TODO we need to write this better maybe subclass create edit hmmm,..
        # get everything from the post   
        editBlogKey = self.request.get('EditBlogKey')
        blogEntry = BlogEntry.get(editBlogKey)
        
        name = self.request.get('nameInput')
        title = self.request.get('titleInput')
        commentText = self.request.get('textarea')
        isHuman = self.request.get('isHuman')
        
        logging.log(logging.INFO, "Creating comment with Blog: " + blogEntry.title + " name: " + name +
                    " title: " + title + " commentText: " + commentText + " isHuman: " + isHuman)
        # we have to submit a comment to a blog
        if editBlogKey == None or not isHuman or not title or not name or not commentText:
            return self.redirect('/') #TODO show them an error or something
    
        comment = CommentEntry()
        
        comment.blog = blogEntry
        comment.name = name
        comment.title = title
        comment.markdown = commentText
        comment.html = BlogRender.render(commentText)
        
        comment.put()
        
        self.redirect('/ViewBlogEntry?blog_id=%s' % blogEntry.key())

class ViewBlogEntry(MainPage):
    def get(self):        
        blogId = self.request.get("blog_id")
        if not blogId:
            return self.redirect('ViewAllEntries')
        self.generateByBlogId(blogId)
        
    def generateByBlogId(self, blogId):
        blogEntry = db.get(blogId)
        template_values = {'blogEntry': blogEntry}
        commentsQuery = CommentEntry.gql('where blog=:blogEntry', blogEntry=blogEntry)
        comments = commentsQuery.fetch(100,0)
        template_values['comments'] = comments
        self.generate('ViewBlogEntry.html', template_values)

class ViewAllEntries(MainPage):
    def get(self):
        currentPage = self.request.get("page")
        if not currentPage:
            currentPage = 0
        else:
            currentPage = int(currentPage)
        query = BlogEntry.all() #db.GqlQuery("SELECT * FROM BlogEntry")
        numRecordsToFetch = 10
        totalRecords = query.count()
        totalPages = totalRecords / numRecordsToFetch
        if currentPage > totalPages:
            currentPage = totalPages
        blogEntries = query.fetch(numRecordsToFetch, numRecordsToFetch * currentPage)
        
        firstPage = 0
        previousPage = currentPage - 1
        nextPage = currentPage + 1
        lastPage = totalPages
        
        template_values = { 'blogEntries' : blogEntries }
        #if firstPage <> lastPage:
        
        if previousPage > firstPage:
            template_values['previousPage'] = str(previousPage)        
        if nextPage < lastPage:
            template_values['nextPage'] = str(nextPage)
        if firstPage <> lastPage:
            template_values['firstPage'] = str(firstPage) #needs string because zero evaluates to false :(
            template_values['currentPage'] = str(currentPage)
            template_values['lastPage'] = str(lastPage)
        
        self.generate('ViewAllEntries.html', template_values)
            
class DeleteBlogEntry(MainPage):
    def get(self):
        if not users.is_current_user_admin():
            return self.redirect(users.create_login_url(self.request.uri))        
        blogEntry = db.get(self.request.get("blog_id"))
        blogEntry.delete()
        self.redirect('/ViewAllEntries')
        
class DeleteCommentEntry(ViewBlogEntry):
    def get(self):
        if not users.is_current_user_admin():
            return self.redirect(users.create_login_url(self.request.uri))
        commentEntry = db.get(self.request.get("comment_id"))
        commentEntry.delete()
        blogId = self.request.get("blog_id")
        self.generateByBlogId(blogId)
         
class ExportAllBlogEntries(MainPage):
    def get(self):
        self.response.headers['Content-Type'] = "text/xml"
        #self.response.out.write('<?xml version="1.0" encoding="ISO-8859-1"?><Blogs></Blogs>')
        xml = '<?xml version="1.0" encoding="ISO-8859-1"?><Blogs>'
        blogEntries = BlogEntry.all()
        for blogEntry in blogEntries:
            xml = xml + blogEntry.to_xml()
        xml = xml + "</Blogs>"
        self.response.out.write(xml)
        
class ViewNamedBlog(ViewBlogEntry):
    def get(self):
        uri = self.request.uri
        blogTitle = uri[uri.rfind('/') + 1:]
        blogTitle = blogTitle.replace("_", " ")
        query = BlogEntry.gql('where title = :title', title = blogTitle)
        blogEntry  = query.get()
        if blogEntry == None:
            self.error(404)
            self.response.out.write("Not found")
            return
        
        self.generateByBlogId(blogEntry.key())
        
def main():
    application = webapp.WSGIApplication([
      ('/', MainPage),
      ('/CreateEditBlog', CreateEditBlog),
      ('/CreateEditBlog.do', CreateEditBlogDo),
      ('/ViewBlogEntry', ViewBlogEntry),
      ('/ViewAllEntries', ViewAllEntries),
      ('/DeleteBlogEntry', DeleteBlogEntry),
      ('/ExportAllBlogEntries', ExportAllBlogEntries),
      ('/articles/.*', ViewNamedBlog),
      ('/AddCommentToBlog.do', AddCommentToBlogDo),
      ('/DeleteCommentEntry', DeleteCommentEntry)
      ], debug=True)    
    run_wsgi_app(application)

if __name__ == '__main__':
    main()

